/// @tags: SA SuffixArray String
#include <algorithm>
#include <cstdio>
#include <cstring>

int const N = 1e6 + 10;
int n, m = 75;
int sa[N], rank[N], cnt[N], tp[N];
char str[N];

inline void sort() {
  for (int i = 0; i <= m; ++i) cnt[i] = 0;
  for (int i = 1; i <= n; ++i) ++cnt[rank[i]];
  for (int i = 1; i <= m; ++i) cnt[i] += cnt[i - 1];
  for (int i = n; i; --i) sa[cnt[rank[tp[i]]]--] = tp[i];
}

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("SuffixArray.in", "r", stdin);
  freopen("SuffixArray.out", "w", stdout);
#endif
#endif

  scanf("%s", str + 1);
  n = strlen(str + 1);
  for (int i = 1; i <= n; ++i) rank[i] = str[i] - '0' + 1, tp[i] = i;
  sort();
  for (int l = 1, p = 0; p < n; m = p, l <<= 1) {
    p = 0;
    for (int i = n - l + 1; i <= n; ++i) tp[++p] = i;
    for (int i = 1; i <= n; ++i)
      if (sa[i] > l) tp[++p] = sa[i] - l;
    sort();
    std::swap(tp, rank);
    rank[sa[1]] = p = 1;
    for (int i = 2; i <= n; ++i)
      rank[sa[i]] =
          (tp[sa[i - 1]] == tp[sa[i]] && tp[sa[i - 1] + l] == tp[sa[i] + l]) ? p : ++p;
  }
  for (int i = 1; i <= n; ++i) { printf("%d ", sa[i]); }
  return 0;
}